package com.anuo.app.study.studyjava;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * #内置的注解(@Override,@SuppressWarnings,@Deprecated)
 * #自定义注解
 * 参考 : https://www.javatpoint.com/java-annotation
 */
public class StudyAnnotation extends MySupperClass {
    public static void main(String[] args) {

        //studySuppressWarnings();
        //studyDeprecated();
        //使用自定义的注解
        studyMyAnnotation();
    }

    /**
     * 自定义注解
     */
    public static void studyMyAnnotation(){
        MySupperClass mySupperClass =new MySupperClass();
        try {
            Method method=mySupperClass.getClass().getMethod("sayHello");
            MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
            System.out.println("value is : " +myAnnotation.value());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }


    }

    /**
     * 这里用 @Override 的好处是
     * #可以表明这个方法是重写方法
     * #可以帮助检查是否重写对没, 如果 方法签名跟父类的不一致, 会报错
     */
    @Override
    public void studyOverride() {

    }

    /**
     * 忽略 编译器的一些异常 比如下面的, 如果有则没有编译警告提示, 如果没有则有编译警告
     */
    @SuppressWarnings("unchecked")
    public static void studySuppressWarnings(){

        ArrayList list=new ArrayList();
        list.add("sonoo");
        list.add("vimal");
        list.add("ratan");

        for(Object obj:list)
            System.out.println(obj);
    }

    /**
     * 表示这个方法在未来的版本会废弃,建议不要使用
     */
    @Deprecated
    public static void studyDeprecated(){

    }
}

class MySupperClass {
    public void studyOverride(){
        System.out.println("hello");
    }

    @MyAnnotation(value = 6)
    public void sayHello(){

    }
}


/**
 *  解释:
 *  #Retention 表示注解的可用级别,枚举如下:
 *      RUNTIME 表示在编译和JVM 运行时 都可用 这个注解;
 *      CLASS 表示在编译后.class 可用
 *      SOURCE 表示在源码级别可用, 编译后不可用
 *  #Target 表示使用的目标, 常见枚举如下:
 *      TYPE 表示用于类
 *      FIELD	表示用于字段
 *      METHOD 表示用于方法
 *      ...
 *  #Documented The @Documented Marks the annotation for inclusion in the documentation.
 *  #在编程时的一些注意事项:
 *      Method should not have any throws clauses
        Method should return one of the following: primitive data types, String, Class, enum or array of these data types.
        Method should not have any parameter.
        We should attach @ just before interface keyword to define annotation.
        It may assign a default value to the method.
 *  参考: https://www.javatpoint.com/custom-annotation
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
 @interface  MyAnnotation{
    int value() default 0;
}
